﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
using ManagedSail;
using System.Drawing.Imaging;

namespace SimpleViewer
{
    public partial class MainForm : Form
    {
        private ImageSequence seq = null;
        private int imageIndex = 0;
        private Sail sailClient = null;

        public MainForm()
        {
            InitializeComponent();
        }

        public void LoadImageSequence(string path)
        {
            try
            {
                seq = ImageSequence.FromFile(path);
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "SimpleViewer");
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            if (seq != null)
            {
                if (seq.Delay > 0)
                {
                    timer.Interval = seq.Delay;
                    timer.Enabled = true;
                }
                else
                    timer.Enabled = false;

                try
                {
                    sailClient = new Sail();
                    sailClient.Init("SimpleViewer.conf", seq.Width, seq.Height);
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, "SAIL initialization failed!");
                    sailClient = null;
                }

                ShowCurrentImage();
            }
        }

        private void MainForm_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == ' ')
                timer_Tick(sender, new EventArgs());
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Left)
            {
                if (imageIndex > 0)
                {
                    imageIndex--;
                    ShowCurrentImage();
                }
            }
            else if (e.KeyCode == Keys.Right)
            {
                if (imageIndex < seq.Files.Length - 1)
                {
                    imageIndex++;
                    ShowCurrentImage();
                }
            }
            base.OnKeyUp(e);
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            imageIndex++;
            if (imageIndex >= seq.Files.Length)
                imageIndex = 0;
            ShowCurrentImage();
        }

        private void ShowCurrentImage()
        {
            Bitmap bmp = Image.FromFile(seq.Files[imageIndex]) as Bitmap;
            pictureBox.Image = bmp;
            if (sailClient != null)
            {
                using (Bitmap buffer = new Bitmap(seq.Width, seq.Height))
                {
                    int srcWidth = bmp.Width;
                    int srcHeight = bmp.Height;

                    if (srcWidth * seq.Height > srcHeight * seq.Width)
                    {
                        if (srcWidth > seq.Width)
                        {
                            srcHeight = (int)(srcHeight * seq.Width/(double)srcWidth);
                            srcWidth = seq.Width;
                        }
                    }
                    else
                    {
                        if (srcHeight > seq.Height)
                        {
                            srcWidth = (int)(srcWidth * seq.Height / (double)srcHeight);
                            srcHeight = seq.Height;
                        }
                    }

                    int originX = (seq.Width - srcWidth) / 2;
                    int originY = (seq.Height - srcHeight) / 2;

                    using (Graphics g = Graphics.FromImage(buffer))
                    {
                        g.Clear(Color.Black);
                        g.DrawImage(bmp, new RectangleF(originX, originY, srcWidth, srcHeight));
                    }

                    BitmapData bmd = buffer.LockBits(new Rectangle(0, 0, buffer.Width, buffer.Height),
                        ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);
                    unsafe
                    {
                        for (int i = 0; i < buffer.Height; i++)
                        {
                            byte *dst = (byte*)sailClient.GetBuffer() + i * buffer.Width * 3;
                            byte *src = (byte*)bmd.Scan0 + i * bmd.Stride;
                            for (int j = 0; j < buffer.Width; j++)
                            {
                                *dst++ = src[2];
                                *dst++ = src[1];
                                *dst++ = src[0];
                                src += 3;
                            }
                        }
                    }
                    buffer.UnlockBits(bmd);

                    sailClient.SwapBuffer(SwapBufferMode.Blocking);
                }
            }
        }
    }
}
